package com.xcf.server.handler;

import com.alibaba.fastjson.JSON;
import com.xcf.model.RpcRequest;
import com.xcf.model.RpcResponse;
import com.xcf.service.impl.UserServiceImpl;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.springframework.context.ApplicationContext;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class UserServerHandler extends ChannelInboundHandlerAdapter {

    private final ApplicationContext applicationContext;

    public UserServerHandler(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        if (null == applicationContext) {
            throw new NullPointerException("ApplicationContext is null");
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        System.out.println("ctx = " + ctx);
        if (!(msg instanceof RpcRequest)) {
            RpcResponse response = new RpcResponse();
            response.setSuccess(false);
            RuntimeException exception = new RuntimeException("Msg protocol is error");
            exception.printStackTrace();
            response.setException(exception.toString());
            ctx.writeAndFlush(response);
            throw exception;
        }
        try {
            RpcRequest request = (RpcRequest) msg;
            String requestId = request.getRequestId();
            Object bean;
            try {
                bean = applicationContext.getBean(requestId);
            } catch (Exception e) {
                bean = applicationContext.getBean(request.getTargetClass());
            }
            Method method = bean.getClass().getMethod(request.getMethodName(), request.getParameterTypes());
            Object obj = method.invoke(bean, request.getParameters());
            RpcResponse response = new RpcResponse();
            response.setSuccess(true);
            response.setData(obj);
            ctx.writeAndFlush(response);
        } catch (Exception e) {
            RpcResponse response = new RpcResponse();
            response.setSuccess(false);
            response.setException(e.toString());
            ctx.writeAndFlush(response);
            throw e;
        }
    }
}
